/**
 * 通用工具函数集合
 * 提供项目中常用的工具方法
 */

/**
 * 数据验证工具
 */
export const validate = {
  /**
   * 验证手机号
   * @param {string} phone - 手机号
   * @returns {boolean} 是否为有效手机号
   */
  phone (phone) {
    return /^1[3-9]\d{9}$/.test(phone)
  },

  /**
   * 验证邮箱
   * @param {string} email - 邮箱地址
   * @returns {boolean} 是否为有效邮箱
   */
  email (email) {
    return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)
  },

  /**
   * 验证密码强度
   * @param {string} password - 密码
   * @returns {Object} 验证结果 { valid: boolean, message: string, strength: number }
   */
  password (password) {
    const result = {
      valid: false,
      message: '',
      strength: 0
    }

    if (!password) {
      result.message = '密码不能为空'
      return result
    }

    if (password.length < 6) {
      result.message = '密码长度不能少于6位'
      return result
    }

    if (password.length > 20) {
      result.message = '密码长度不能超过20位'
      return result
    }

    // 计算密码强度
    let strength = 0
    if (/[a-z]/.test(password)) strength++
    if (/[A-Z]/.test(password)) strength++
    if (/\d/.test(password)) strength++
    if (/[!@#$%^&*(),.?":{}|<>]/.test(password)) strength++

    result.valid = true
    result.strength = strength

    if (strength === 1) {
      result.message = '密码强度：弱'
    } else if (strength === 2) {
      result.message = '密码强度：中'
    } else if (strength >= 3) {
      result.message = '密码强度：强'
    }

    return result
  },

  /**
   * 验证身份证号
   * @param {string} idCard - 身份证号
   * @returns {boolean} 是否为有效身份证号
   */
  idCard (idCard) {
    return /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/.test(idCard)
  },

  /**
   * 验证车牌号
   * @param {string} plateNumber - 车牌号
   * @returns {boolean} 是否为有效车牌号
   */
  plateNumber (plateNumber) {
    return /^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领A-Z]{1}[A-Z]{1}[A-Z0-9]{4}[A-Z0-9挂学警港澳]{1}$/.test(plateNumber)
  }
}

/**
 * 格式化工具
 */
export const format = {
  /**
   * 格式化手机号（中间4位用*代替）
   * @param {string} phone - 手机号
   * @returns {string} 格式化后的手机号
   */
  phone (phone) {
    if (!phone || phone.length !== 11) {
      return phone
    }
    return phone.replace(/(\d{3})\d{4}(\d{4})/, '$1****$2')
  },

  /**
   * 格式化金额（千分位分隔）
   * @param {number|string} amount - 金额
   * @param {number} decimals - 小数位数，默认2位
   * @returns {string} 格式化后的金额
   */
  currency (amount, decimals = 2) {
    if (isNaN(amount)) return '0.00'

    const num = parseFloat(amount)
    return num.toLocaleString('zh-CN', {
      minimumFractionDigits: decimals,
      maximumFractionDigits: decimals
    })
  },

  /**
   * 格式化日期时间
   * @param {Date|string|number} date - 日期
   * @param {string} format - 格式字符串，默认 'YYYY-MM-DD HH:mm:ss'
   * @returns {string} 格式化后的日期时间
   */
  dateTime (date, format = 'YYYY-MM-DD HH:mm:ss') {
    if (!date) return ''

    const d = new Date(date)
    if (isNaN(d.getTime())) return ''

    const year = d.getFullYear()
    const month = String(d.getMonth() + 1).padStart(2, '0')
    const day = String(d.getDate()).padStart(2, '0')
    const hours = String(d.getHours()).padStart(2, '0')
    const minutes = String(d.getMinutes()).padStart(2, '0')
    const seconds = String(d.getSeconds()).padStart(2, '0')

    return format
      .replace('YYYY', year)
      .replace('MM', month)
      .replace('DD', day)
      .replace('HH', hours)
      .replace('mm', minutes)
      .replace('ss', seconds)
  },

  /**
   * 格式化相对时间（多久之前）
   * @param {Date|string|number} date - 日期
   * @returns {string} 相对时间
   */
  relativeTime (date) {
    if (!date) return ''

    const d = new Date(date)
    if (isNaN(d.getTime())) return ''

    const now = new Date()
    const diff = now.getTime() - d.getTime()

    const minute = 60 * 1000
    const hour = 60 * minute
    const day = 24 * hour
    const week = 7 * day
    const month = 30 * day
    const year = 365 * day

    if (diff < minute) {
      return '刚刚'
    } else if (diff < hour) {
      return Math.floor(diff / minute) + '分钟前'
    } else if (diff < day) {
      return Math.floor(diff / hour) + '小时前'
    } else if (diff < week) {
      return Math.floor(diff / day) + '天前'
    } else if (diff < month) {
      return Math.floor(diff / week) + '周前'
    } else if (diff < year) {
      return Math.floor(diff / month) + '月前'
    } else {
      return Math.floor(diff / year) + '年前'
    }
  },

  /**
   * 格式化文件大小
   * @param {number} bytes - 字节数
   * @returns {string} 格式化后的文件大小
   */
  fileSize (bytes) {
    if (bytes === 0) return '0 B'

    const k = 1024
    const sizes = ['B', 'KB', 'MB', 'GB', 'TB']
    const i = Math.floor(Math.log(bytes) / Math.log(k))

    return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]
  }
}

/**
 * 存储工具
 */
export const storage = {
  /**
   * 设置本地存储
   * @param {string} key - 存储键
   * @param {any} value - 存储值
   * @param {number} expire - 过期时间（毫秒），可选
   */
  set (key, value, expire) {
    try {
      const data = {
        value,
        timestamp: Date.now(),
        expire: expire ? Date.now() + expire : null
      }
      uni.setStorageSync(key, JSON.stringify(data))
    } catch (error) {
      console.error('设置存储失败:', error)
    }
  },

  /**
   * 获取本地存储
   * @param {string} key - 存储键
   * @param {any} defaultValue - 默认值
   * @returns {any} 存储值
   */
  get (key, defaultValue = null) {
    try {
      const dataStr = uni.getStorageSync(key)
      if (!dataStr) return defaultValue

      const data = JSON.parse(dataStr)

      // 检查是否过期
      if (data.expire && Date.now() > data.expire) {
        uni.removeStorageSync(key)
        return defaultValue
      }

      return data.value
    } catch (error) {
      console.error('获取存储失败:', error)
      return defaultValue
    }
  },

  /**
   * 删除本地存储
   * @param {string} key - 存储键
   */
  remove (key) {
    try {
      uni.removeStorageSync(key)
    } catch (error) {
      console.error('删除存储失败:', error)
    }
  },

  /**
   * 清空本地存储
   */
  clear () {
    try {
      uni.clearStorageSync()
    } catch (error) {
      console.error('清空存储失败:', error)
    }
  }
}

/**
 * URL工具
 */
export const url = {
  /**
   * 解析URL参数
   * @param {string} urlString - URL字符串
   * @returns {Object} 参数对象
   */
  parseQuery (urlString = '') {
    const query = {}
    const queryString = urlString.split('?')[1] || ''

    queryString.split('&').forEach(param => {
      const [key, value] = param.split('=')
      if (key) {
        query[decodeURIComponent(key)] = decodeURIComponent(value || '')
      }
    })

    return query
  },

  /**
   * 构建URL参数字符串
   * @param {Object} params - 参数对象
   * @returns {string} 参数字符串
   */
  buildQuery (params) {
    return Object.keys(params)
      .filter(key => params[key] !== null && params[key] !== undefined)
      .map(key => `${encodeURIComponent(key)}=${encodeURIComponent(params[key])}`)
      .join('&')
  },

  /**
   * 拼接URL
   * @param {string} base - 基础URL
   * @param {Object} params - 参数对象
   * @returns {string} 完整URL
   */
  build (base, params = {}) {
    const queryString = this.buildQuery(params)
    return queryString ? `${base}?${queryString}` : base
  }
}

/**
 * 设备工具
 */
export const device = {
  /**
   * 获取设备信息
   * @returns {Promise<Object>} 设备信息
   */
  getInfo () {
    return new Promise((resolve) => {
      uni.getSystemInfo({
        success: (info) => {
          resolve({
            brand: info.brand,
            model: info.model,
            system: info.system,
            platform: info.platform,
            version: info.version,
            screenWidth: info.screenWidth,
            screenHeight: info.screenHeight,
            windowWidth: info.windowWidth,
            windowHeight: info.windowHeight,
            statusBarHeight: info.statusBarHeight,
            safeArea: info.safeArea
          })
        },
        fail: () => {
          resolve({})
        }
      })
    })
  },

  /**
   * 判断是否为iOS设备
   * @returns {boolean} 是否为iOS设备
   */
  isIOS () {
    return uni.getSystemInfoSync().platform === 'ios'
  },

  /**
   * 判断是否为Android设备
   * @returns {boolean} 是否为Android设备
   */
  isAndroid () {
    return uni.getSystemInfoSync().platform === 'android'
  },

  /**
   * 判断是否为微信小程序
   * @returns {boolean} 是否为微信小程序
   */
  isWechatMiniprogram () {
    // #ifdef MP-WEIXIN
    return true
    // #endif
    // #ifndef MP-WEIXIN
    return false
    // #endif
  }
}

/**
 * 防抖函数
 * @param {Function} func - 要防抖的函数
 * @param {number} delay - 延迟时间（毫秒）
 * @returns {Function} 防抖后的函数
 */
export function debounce (func, delay = 300) {
  let timer = null
  return function (...args) {
    if (timer) clearTimeout(timer)
    timer = setTimeout(() => {
      func.apply(this, args)
    }, delay)
  }
}

/**
 * 节流函数
 * @param {Function} func - 要节流的函数
 * @param {number} delay - 间隔时间（毫秒）
 * @returns {Function} 节流后的函数
 */
export function throttle (func, delay = 300) {
  let timer = null
  return function (...args) {
    if (!timer) {
      timer = setTimeout(() => {
        func.apply(this, args)
        timer = null
      }, delay)
    }
  }
}

/**
 * 深拷贝
 * @param {any} obj - 要拷贝的对象
 * @returns {any} 拷贝后的对象
 */
export function deepClone (obj) {
  if (obj === null || typeof obj !== 'object') {
    return obj
  }

  if (obj instanceof Date) {
    return new Date(obj)
  }

  if (obj instanceof Array) {
    return obj.map(item => deepClone(item))
  }

  if (typeof obj === 'object') {
    const cloned = {}
    Object.keys(obj).forEach(key => {
      cloned[key] = deepClone(obj[key])
    })
    return cloned
  }
}

/**
 * 生成唯一ID
 * @returns {string} 唯一ID
 */
export function generateId () {
  return Date.now().toString(36) + Math.random().toString(36).substr(2)
}

// 默认导出
export default {
  validate,
  format,
  storage,
  url,
  device,
  debounce,
  throttle,
  deepClone,
  generateId
}